/*
 * To change this template, choose Tools | Templates
 * and open the template in the editor.
 */
package Almacenamiento.TAREA_LABORATORIO6;

import Almacenamiento.GestorIOPagina;
import Almacenamiento.GestorIOTupla;
import Almacenamiento.IdentificadorPagina;
import Almacenamiento.Relacion;
import Almacenamiento.Tupla;
import java.util.ArrayList;
import java.util.Iterator;
import java.util.List;

/**
 *
 * @author User
 */
public class Pagina_Ranura implements  Iterable<Tupla> {
    int nroTuplas;
    List<Tupla> ListaTuplas;
    ArrayList<Ranura_Cabecera> Cabeceras;
     int longitud_pagina=4096;// en bytes
     IdentificadorPagina idPagina;
    Relacion r;
    int fin_cabeceras =4 ; //ya se agregó el nro de tuplas

    public Pagina_Ranura( Relacion r,IdentificadorPagina idPagina) {
        this.idPagina = idPagina;
        this.r = r;
        
        this.nroTuplas = 0;
        this.ListaTuplas = new ArrayList<Tupla>();
        this.Cabeceras = new ArrayList<Ranura_Cabecera>();
        Ranura_Cabecera cabeceran= new Ranura_Cabecera(4096, 0);
        Cabeceras.add(cabeceran);
        idPagina = new IdentificadorPagina(null, 0);
        
    }
    

    public Pagina_Ranura(int nroTuplas, List<Tupla> ListaTuplas, ArrayList<Ranura_Cabecera> Caberceras) {
        this.nroTuplas = nroTuplas;
        this.ListaTuplas = ListaTuplas;
        this.Cabeceras = Caberceras;
        Ranura_Cabecera cabeceran= new Ranura_Cabecera(4096, 0);
        Caberceras.add(cabeceran);
        idPagina = new IdentificadorPagina(null, 0);
    }

    public Pagina_Ranura() {
        nroTuplas=0;
        ListaTuplas=  new ArrayList<Tupla>();
        Cabeceras= new ArrayList<Ranura_Cabecera>();
        Ranura_Cabecera cabeceran= new Ranura_Cabecera(4096, 0);
        Cabeceras.add(cabeceran);
        idPagina = new IdentificadorPagina(null, 0);
        
        
    }
    
    public String AgregarTupla(Tupla t)
    {
        // AÑADIENDO LA CABECERA
        //obtener el tamaño en bytes de la tupla que se esta añadiendo;
       
        GestorIOTupla gt = new GestorIOTupla(r, idPagina.getNombreArchivo());
        int tamanio_tupla_actual= gt.byteSize(t);
        //obtener el fin del expacio libre en la pagina
        int fin_el_antes= Cabeceras.get(Cabeceras.size()-1).finEspacioLibre;
        
        if (fin_el_antes - fin_cabeceras >=tamanio_tupla_actual) { //hay espacio
        int fin_el_actual= fin_el_antes - tamanio_tupla_actual;
        Ranura_Cabecera cabeceran= new Ranura_Cabecera(fin_el_actual, tamanio_tupla_actual);
        Cabeceras.add(cabeceran);  
        nroTuplas++;
        fin_cabeceras +=8; 
        //AÑADIENDO LA TUPLA EN SI  
        ListaTuplas.add(t);
        return "true";
        }
        else{
        return "No hay espacio en pagina";
        }       
         
     
    }

    public ArrayList<Ranura_Cabecera> getCabeceras() {
        return Cabeceras;
    }

    public List<Tupla> getListaTuplas() {
        return ListaTuplas;
    }

    public int getFin_cabeceras() {
        return fin_cabeceras;
    }

    public IdentificadorPagina getIdPagina() {
        return idPagina;
    }

    public int getLongitud_pagina() {
        return longitud_pagina;
    }

    public int getNroTuplas() {
        return nroTuplas;
    }

    public void setCabeceras(ArrayList<Ranura_Cabecera> Cabeceras) {
        this.Cabeceras = Cabeceras;
    }

    public void setListaTuplas(List<Tupla> ListaTuplas) {
        this.ListaTuplas = ListaTuplas;
    }

    public void setFin_cabeceras(int fin_cabeceras) {
        this.fin_cabeceras = fin_cabeceras;
    }

    public void setIdPagina(IdentificadorPagina idPagina) {
        this.idPagina = idPagina;
    }

    public void setLongitud_pagina(int longitud_pagina) {
        this.longitud_pagina = longitud_pagina;
    }

    public void setNroTuplas(int nroTuplas) {
        this.nroTuplas = nroTuplas;
    }

    public Relacion getRelacion() {
        return r;
    }

     @Override
    public Iterator<Tupla> iterator() {
        return new IteradorDePagina();
    }

    /**
     * Clase interna que implementa un iterator de tupla
     * DIGA 18 de Junio - 022600
     */
    private class IteradorDePagina implements Iterator<Tupla> {

        /** El actual indice del iterator. */
        private int indiceActual;

        /**
         * Constructor de un nuevo iterator para el contenido de la página.
         */
        public IteradorDePagina() {
            indiceActual = 0;
        }

        /**
         * Verificar si hay mas tuplas en la página.
         *
         * @return <code>true</code> si hay mas tuplas
         * en la página, <code>false</code> en caso contrario.
         */
        @Override
        public boolean hasNext() {
            return indiceActual < ListaTuplas.size();
        }

        /**
         * Devuelve la siguiente tupla del iterator.
         *
         * @return la siguiente tupla del iterator.
         */
        @Override
        public Tupla next() {
            return ListaTuplas.get(indiceActual++);
        }

        /**
         * Elimina la última tupla devuelta por el iterador.
         */
        @Override
        public void remove() {
            // falta implementar
        }
    }

    /**
     * Devolver un representación textual de la página.
     * 
     * @return representación textual de la página.
     */
    @Override
    public String toString() {

        //
        System.out.println("PAGINA:");
        System.out.println("ARchivo:"+ idPagina.getNombreArchivo());
        System.out.println("Numero de pagina:" + idPagina.getNumero());
        System.out.println("   CABECERA:");
         
        for (int i = 0; i < Cabeceras.size(); i++) {
         System.out.println(Cabeceras.get(i).toString()); 
        }
        
        System.out.println("   TUPLAS:");
        
        for (int i = 0; i < ListaTuplas.size(); i++) {
         System.out.println(ListaTuplas.get(i).toString()); 
        }
        
        return "Fin- pagina";
    }
    
    
    
    
}
